home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 5 / Example 5.8 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.7 KB  |  282 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 5.8: Progressive Meshes                            //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include <vector>
  9. #include "debug.h"
  10. #include "mesh.h"
  11.  
  12. class APPLICATION
  13. {
  14.     public:
  15.         APPLICATION();
  16.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  17.         HRESULT Update(float deltaTime);
  18.         HRESULT Render();
  19.         HRESULT Cleanup();
  20.         HRESULT Quit();
  21.  
  22.     private:
  23.         IDirect3DDevice9* m_pDevice; 
  24.         MESH *m_pFarmerMesh;
  25.         MESHINSTANCE m_farmer1, m_farmer2;
  26.  
  27.         D3DLIGHT9 m_light;
  28.         bool m_wireframe;
  29.         HWND m_mainWindow;
  30.         ID3DXFont *m_pFont;
  31. };
  32.  
  33. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  34. {
  35.     APPLICATION app;
  36.  
  37.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  38.         return 0;
  39.  
  40.     MSG msg;
  41.     memset(&msg, 0, sizeof(MSG));
  42.     int startTime = timeGetTime(); 
  43.  
  44.     while(msg.message != WM_QUIT)
  45.     {
  46.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  47.         {
  48.             ::TranslateMessage(&msg);
  49.             ::DispatchMessage(&msg);
  50.         }
  51.         else
  52.         {    
  53.             int t = timeGetTime();
  54.             float deltaTime = (t - startTime)*0.001f;
  55.  
  56.             app.Update(deltaTime);
  57.             app.Render();
  58.  
  59.             startTime = t;
  60.         }
  61.     }
  62.  
  63.     app.Cleanup();
  64.  
  65.     return msg.wParam;
  66. }
  67.  
  68. APPLICATION::APPLICATION()
  69. {
  70.     m_pDevice = NULL; 
  71.     m_mainWindow = 0;
  72.     m_pFarmerMesh = NULL;
  73.     m_pFont = NULL;
  74.     m_wireframe = false;
  75.     srand(GetTickCount());
  76. }
  77.  
  78. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  79. {
  80.     debug.Print("Application initiated");
  81.  
  82.     //Create Window Class
  83.     WNDCLASS wc;
  84.     memset(&wc, 0, sizeof(WNDCLASS));
  85.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  86.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  87.     wc.hInstance     = hInstance;
  88.     wc.lpszClassName = "D3DWND";
  89.  
  90.     //Register Class and Create new Window
  91.     RegisterClass(&wc);
  92.     m_mainWindow = CreateWindow("D3DWND", "Example 5.8: Progressive Meshes", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  93.     SetCursor(NULL);
  94.     ShowWindow(m_mainWindow, SW_SHOW);
  95.     UpdateWindow(m_mainWindow);
  96.  
  97.     //Create IDirect3D9 Interface
  98.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  99.  
  100.     if(d3d9 == NULL)
  101.     {
  102.         debug.Print("Direct3DCreate9() - FAILED");
  103.         return E_FAIL;
  104.     }
  105.  
  106.     //Check that the Device supports what we need from it
  107.     D3DCAPS9 caps;
  108.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  109.  
  110.     //Hardware Vertex Processing or not?
  111.     int vp = 0;
  112.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  113.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  114.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  115.  
  116.     //Check vertex & pixelshader versions
  117.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  118.     {
  119.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  120.     }
  121.  
  122.     //Set D3DPRESENT_PARAMETERS
  123.     D3DPRESENT_PARAMETERS d3dpp;
  124.     d3dpp.BackBufferWidth            = width;
  125.     d3dpp.BackBufferHeight           = height;
  126.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  127.     d3dpp.BackBufferCount            = 1;
  128.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  129.     d3dpp.MultiSampleQuality         = 0;
  130.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  131.     d3dpp.hDeviceWindow              = m_mainWindow;
  132.     d3dpp.Windowed                   = windowed;
  133.     d3dpp.EnableAutoDepthStencil     = true; 
  134.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  135.     d3dpp.Flags                      = 0;
  136.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  137.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  138.  
  139.     //Create the IDirect3DDevice9
  140.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  141.                                  vp, &d3dpp, &m_pDevice)))
  142.     {
  143.         debug.Print("Failed to create IDirect3DDevice9");
  144.         return E_FAIL;
  145.     }
  146.  
  147.     //Release IDirect3D9 interface
  148.     d3d9->Release();
  149.  
  150.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  151.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  152.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  153.  
  154.     //Create m_light
  155.     ::ZeroMemory(&m_light, sizeof(m_light));
  156.     m_light.Type      = D3DLIGHT_DIRECTIONAL;
  157.     m_light.Ambient   = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  158.     m_light.Diffuse   = D3DXCOLOR(0.9, 0.9, 0.9, 1.0f);
  159.     m_light.Specular  = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  160.     m_light.Direction = D3DXVECTOR3(0.0f, -1.0f, 0.0f);
  161.     m_pDevice->SetLight(0, &m_light);
  162.     m_pDevice->LightEnable(0, true);
  163.  
  164.     //Load mech
  165.     m_pFarmerMesh = new MESH("objects/farmer.x", m_pDevice);
  166.  
  167.     m_farmer1.SetMesh(m_pFarmerMesh);
  168.     m_farmer2.SetMesh(m_pFarmerMesh);
  169.     m_farmer1.SetPosition(D3DXVECTOR3(-2.5f, 0.0f, 0.0f));
  170.     m_farmer2.SetPosition(D3DXVECTOR3(2.5f, 0.0f, 0.0f));
  171.  
  172.     //Set sampler state
  173.     for(int i=0;i<4;i++)
  174.     {
  175.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  176.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  177.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  178.     }
  179.  
  180.     return S_OK;
  181. }
  182.  
  183. HRESULT APPLICATION::Update(float deltaTime)
  184. {
  185.     //Control camera
  186.     D3DXMATRIX  matWorld;
  187.     D3DXMatrixIdentity(&matWorld);
  188.     m_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
  189.  
  190.     //Rotate farmers
  191.     m_farmer1.SetRotation(m_farmer1.m_rot + D3DXVECTOR3(0.0f, deltaTime * 0.5f, 0.0f));
  192.     if(m_farmer1.m_rot.y > D3DX_PI * 2.0f)m_farmer1.m_rot.y -= D3DX_PI * 2.0f;
  193.  
  194.     m_farmer2.SetRotation(m_farmer2.m_rot + D3DXVECTOR3(0.0f, deltaTime * 0.5f, 0.0f));
  195.     if(m_farmer2.m_rot.y > D3DX_PI * 2.0f)m_farmer2.m_rot.y -= D3DX_PI * 2.0f;
  196.  
  197.     if(KEYDOWN(VK_DOWN))
  198.     {
  199.         m_farmer2.SetLOD(m_farmer2.GetNumProgressiveFaces() - 5);
  200.         Sleep(30);
  201.     }
  202.     else if(KEYDOWN(VK_UP))
  203.     {
  204.         m_farmer2.SetLOD(m_farmer2.GetNumProgressiveFaces() + 5);
  205.         Sleep(30);
  206.     }
  207.     else if(KEYDOWN('W'))
  208.     {
  209.         m_wireframe = !m_wireframe;
  210.         Sleep(300);
  211.     }
  212.     else if(KEYDOWN(VK_ESCAPE))
  213.         Quit();
  214.  
  215.     return S_OK;
  216. }    
  217.  
  218.  
  219. HRESULT APPLICATION::Render()
  220. {
  221.     // Clear the viewport
  222.     m_pDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L );
  223.  
  224.     // Begin the scene 
  225.     if(SUCCEEDED(m_pDevice->BeginScene()))
  226.     {
  227.         //Set camera
  228.         D3DXMATRIX view, proj;
  229.         D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 10.0f, -50.0f), &D3DXVECTOR3(0.0f, 3.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  230.         D3DXMatrixOrthoLH(&proj, 10.0f, 9.0f, 0.1f, 1000.0f);
  231.         m_pDevice->SetTransform(D3DTS_VIEW, &view);
  232.         m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  233.  
  234.         if(m_wireframe)m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);    
  235.         else m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
  236.  
  237.         m_farmer1.Render();
  238.         m_farmer2.RenderProgressive();
  239.  
  240.         //Number of polygons
  241.         char number[50];
  242.         std::string text = _itoa(m_farmer2.GetNumProgressiveFaces(), number, 10);
  243.         text += " polygons (UP/DOWN Arrow)";
  244.         
  245.         RECT r[] = {{170, 520, 0, 0}, {530, 520, 0, 0}, {470, 540, 0, 0}, {130, 540, 0, 0}};
  246.         m_pFont->DrawText(NULL, "Original", -1, &r[0], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  247.         m_pFont->DrawText(NULL, "Progressive Mesh", -1, &r[1], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  248.         m_pFont->DrawText(NULL, text.c_str(), -1, &r[2], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  249.         m_pFont->DrawText(NULL, "(W)ireframe On/Off", -1, &r[3], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);        
  250.  
  251.         // End the scene.
  252.         m_pDevice->EndScene();
  253.         m_pDevice->Present(0, 0, 0, 0);
  254.     }
  255.  
  256.     return S_OK;
  257. }
  258.  
  259. HRESULT APPLICATION::Cleanup()
  260. {
  261.     try
  262.     {
  263.         m_pFont->Release();
  264.  
  265.         if(m_pFarmerMesh != NULL)
  266.             m_pFarmerMesh->Release();
  267.  
  268.         m_pDevice->Release();
  269.  
  270.         debug.Print("Application terminated");
  271.     }
  272.     catch(...){}
  273.  
  274.     return S_OK;
  275. }
  276.  
  277. HRESULT APPLICATION::Quit()
  278. {
  279.     ::DestroyWindow(m_mainWindow);
  280.     ::PostQuitMessage(0);
  281.     return S_OK;
  282. }